package com.awesome.todo.database;

import java.util.ArrayList;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.CursorIndexOutOfBoundsException;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.awesome.todo.Task;

enum Category {
	Personal, School, Work, NULL
}

/**
 * This is the class that handles all database interaction with the Task table.
 * This is a comprehensive layer on top of the internal SQLite database. This is
 * the *ONLY* place that handles SQLite inserts, queries, and deletes to the
 * Task table. Other classes must call methods from this class if they wish to
 * use data contained in the database.
 * 
 * @author Doug Black
 * 
 */
public class TaskDataSource {

	private SQLiteDatabase database;
	private TaskTable taskTable;
	@SuppressWarnings("static-access")
	private String[] allColumns = { taskTable.COLUMN_ID, taskTable.COLUMN_NAME, taskTable.COLUMN_DATE,
			 taskTable.COLUMN_ADDRESS, taskTable.COLUMN_CITY, taskTable.COLUMN_STATE, taskTable.COLUMN_DESCRIPTION, taskTable.COLUMN_TYPE,
			taskTable.COLUMN_USER_ID, taskTable.COLUMN_COMPLETED };

	public TaskDataSource(Context context) {
		taskTable = new TaskTable(context);
	}

	/**
	 * This opens the Task table for writing.
	 * 
	 * @throws SQLException
	 */
	public void open() throws SQLException {
		database = taskTable.getWritableDatabase();
	}

	/**
	 * This closes the Task table.
	 */
	public void close() {
		taskTable.close();
	}

	/**
	 * This inserts a new row in the Task table and returns a Task object with
	 * the corresponding values.
	 * @param type2 
	 * 
	 */
	public Task createTask(String name, String date, String address, String city, String state, String description,
			String type, long userId) {

		this.open();
		ContentValues values = new ContentValues();
		values.put(TaskTable.COLUMN_NAME, name);
		values.put(TaskTable.COLUMN_DATE, date);
		values.put(TaskTable.COLUMN_ADDRESS, address);
		values.put(TaskTable.COLUMN_CITY, city);
		values.put(TaskTable.COLUMN_STATE, state);
		values.put(TaskTable.COLUMN_DESCRIPTION, description);
		values.put(TaskTable.COLUMN_TYPE, type);
		values.put(TaskTable.COLUMN_USER_ID, userId);
		values.put(TaskTable.COLUMN_COMPLETED, "false");

		long insertId = database.insert(TaskTable.TABLE_TASK, null, values);

		Cursor cursor = database.query(TaskTable.TABLE_TASK, allColumns, TaskTable.COLUMN_NAME + " = " + insertId,
				null, null, null, null, null);

		Log.i(TaskDataSource.class.toString(), "New item created with name: " + insertId);
		cursor.moveToFirst();
		Task newTask = cursorToTask(cursor);
		cursor.close();
		this.close();
		return newTask;
	}

	
//	public ArrayList<Task> getTasksForUserIdByDate(long userId) {
//		this.open();
//		Cursor cursor = database.query(TaskTable.TABLE_TASK, allColumns, TaskTable.COLUMN_USER_ID + " = '" + userId + "' AND ", null, null, null, null);
//	}

	/**
	 * This gets all of the tasks for the given user.
	 * 
	 * @param userId
	 *            the ID of the given user
	 * @return the arraylist of all Tasks owned by this user.
	 */
	public ArrayList<Task> getAllTasksForUserId(long userId) {
		this.open();
		Cursor cursor = database.query(TaskTable.TABLE_TASK, allColumns, TaskTable.COLUMN_USER_ID + " = '" + userId
				+ "'", null, null, null, null);
		cursor.moveToFirst();

		ArrayList<Task> tasks = cursorToTasks(cursor);
		cursor.close();
		this.close();
		return tasks;
	}

	/**
	 * This deletes the row in the Task table corresponding to the ID value of
	 * the passed in Task object
	 * 
	 * @param Task
	 *            the Task to be deleted
	 */
	public void deleteTask(Task task) {
		this.open();
		long id = task.getId();
		System.out.println("Task deleted with id: " + id);
		database.delete(TaskTable.TABLE_TASK, TaskTable.COLUMN_NAME + " = " + id, null);
		this.close();
	}

	/**
	 * Converts a row from the Task table to a java Task object.
	 * 
	 * @param cursor
	 *            the cursor pointing to the given row in the Task table
	 * @return a Task object with corresponding field values
	 */

	public Task cursorToTask(Cursor cursor) {
		Task task = new Task();
		try {
			task.setId(cursor.getLong(0));
			task.setName(cursor.getString(1));
			task.setDate(cursor.getString(2));
			task.setAddress(cursor.getString(3));
			task.setCity(cursor.getString(4));
			task.setState(cursor.getString(5));
			task.setDescription(cursor.getString(6));
			task.setType(cursor.getString(7));
			task.setUserId(cursor.getLong(8));
			Log.i("INFO", "Task database completed status for " + cursor.getString(1) + ": " + cursor.getString(8));
			task.setCompleted(Boolean.parseBoolean(cursor.getString(9)));
		} catch (CursorIndexOutOfBoundsException e) {
			task = null;
		}
		return task;
	}

	/**
	 * Returns a list of Tasks corresponding to a given cursor
	 * @param cursor
	 * @return
	 */
	public ArrayList<Task> cursorToTasks(Cursor cursor) {

		ArrayList<Task> tasks = new ArrayList<Task>();

		while (!cursor.isAfterLast()) {
			tasks.add(cursorToTask(cursor));
			cursor.moveToNext();
		}

		return tasks;
	}
	
	/**
	 * Updates a given task's completed status.
	 * @param id
	 * @param completed
	 */
	public void setCompletedTask(Long id, Boolean completed) {
		this.open();
		ContentValues val = new ContentValues();
		val.put(TaskTable.COLUMN_COMPLETED, completed.toString());
		database.update(TaskTable.TABLE_TASK, val, TaskTable.COLUMN_ID + " = '" + id + "'", null);
		Log.i("INFO", "Updated task with task ID: " + id + " with completion status: " + completed.toString());
		this.close();
		
	}

}